<?php
/* --- 若无特别需求,请勿修改此文件,谢谢 --- */
/**
 * 自定义Session的存储方式
 */
!defined('IN_FRAME') && die('404 Page');
class SessionCache {
    private $intLifeSec = 3600;
    private $strType = '';
    private $blnDb = false;
    private $strTable = 't_sess';
    private $dbConn = null;
    private $objDes = null;
    
    /**
     * $strType = native | apc | memcache | files | mysql
     * $strDesKey = 8位的密钥
     */
    public function __construct($strType = '', $strDesKey = '') {
        empty($strType) && $strType = 'native';
        if ('native' != $strType) { // 如果不用原生的SESSION
            $this->strType = $strType;
            $this->blnDb = in_array($this->strType, array('mysql'));
            if ($this->blnDb) {
                if ($this->strType == 'mysql') {
                    $this->dbConn = Db::getInstance();
                    if (!in_array($this->strTable, $this->dbConn->showTables())) {
                        $strSql = <<<SQL
CREATE TABLE IF NOT EXISTS `{$this->strTable}` (
  `id` varchar(255) NOT NULL,
  `data` varchar(20479) DEFAULT NULL,
  `end` bigint(20) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MEMORY
SQL;
                        $this->dbConn->query($strSql);
                    }
                }
            }
            $this->objDes = new DES($strDesKey);
            session_set_save_handler(
                array(&$this, 'open'),
                array(&$this, 'close'),
                array(&$this, 'read'),
                array(&$this, 'write'),
                array(&$this, 'destroy'),
                array(&$this, 'gc')
            );
        }
    	session_start();
    }
    
    private function setCacheStorage() {
        if (!$this->blnDb) {
            phpFastCache::$storage = $this->strType;
            if ('files' == $this->strType) {
                phpFastCache::$securityKey = 'session';
                phpFastCache::$path = CACHES_PATH;
            }
        }
    }
    
    public function read($id) {
        $re = false;
        $id = md5($id . $this->strDesKey);
        if (!$this->blnDb) {
            $this->setCacheStorage();
            $re = phpFastCache::get($id);
        } else {
            if ($this->strType == 'mysql') {
                $arrOne = $this->dbConn->getOne($this->strTable, '`id` = "' . addslashes($id) . '" AND `end` >= ' . time(), '`data`');
                is_array($arrOne) && $re = $arrOne['data'];
            }
        }
        $re && $re = $this->objDes->decode($re);
        return $re;
    }
    
    public function write($id, $data) {
        $re = false;
        $id = md5($id . $this->strDesKey);
        $data = $this->objDes->encode($data);
        if (!$this->blnDb) {
            $this->setCacheStorage();
            $re = phpFastCache::set($id, $data, $this->intLifeSec);
        } else {
            if ($this->strType == 'mysql') {
                $re = $this->dbConn->replace($this->strTable, array('id' => $id, 'data' => $data, 'end' => (time() + $this->intLifeSec)));
            }
        }
        return $re;
    }
    
    public function destroy($id) {
        $re = false;
        $id = md5($id . $this->strDesKey);
        if (!$this->blnDb) {
            $this->setCacheStorage();
            $re = phpFastCache::delete($id);
        } else {
            if ($this->strType == 'mysql') {
                $re = $this->dbConn->delete($this->strTable, array('id' => $id));
            }
        }
        return $re;
    }
    
    public function open() {
        return true;
    }
    
    public function close() {
        if ($this->blnDb) {
            if ($this->strType == 'mysql') {
                Db::close();
            }
        }
        return true;
    }
    
    public function gc() {
        if ($this->blnDb) {
            if ($this->strType == 'mysql') {
                $this->dbConn->delete($this->strTable, '`end` < ' . time());
            }
        } else {
            $this->setCacheStorage();
            phpFastCache::cleanup();
        }
        return true;
    }
}